Skip to content

Conversation

@kyp44
Copy link
Contributor

@kyp44 kyp44 commented Oct 3, 2025

Summary

NOTE: Marking as draft because this depends on a merge of PR #935.

A number of Tier 1 BSP examples that use USB as a serial device emit compiler warnings related to the necessary use of static mut. Additionally, some are not used in a safe way.

This updates these examples to suppress the warnings and make things safe by accessing the USB device in the main program (i.e. not in the USB polling interrupt) only in crticial sections that disable applicable USB interrupts.

The usability issue with USB in embedded applications is a known issue, and the best solution for these examples was discussed in Matrix.

See the commit log for details about which BSP examples were changed, and not that each BSP crate was changed in a separate commit per the guideline.

Checklist

  • All new or modified code is well documented, especially public items
  • No new warnings or clippy suggestions have been introduced - CI will deny clippy warnings by default! You may #[allow] certain lints where reasonable, but ideally justify those with a short comment.

@rnd-ash
Copy link
Contributor

rnd-ash commented Oct 3, 2025

I had a look at this, overall quite happy with things,

However, I think the usb_get and usb_free methods that are used are a little bit over complex for an example (Especially making the user have to manually create a critical section).

In some other projects I have done with USB, I have gotten around the static mut like so

Incomplete example:

pub static USB_BUS_ALLOC: StaticCell<UsbBusAllocator<UsbBus>> = StaticCell::new();

// Data to be accessed whenever an ISR occurs on USB
pub struct UsbIsrInfo<'a> {
    pub dev: UsbDevice<'a, UsbBus>,
    pub class: SomeClassLikeSerial<'a, UsbBus>,
}

pub static USB: Mutex<RefCell<Option<UsbIsrInfo<'static>>>> = Mutex::new(RefCell::new(None));

#[inline(always)]
pub fn with_cs_mutex<R, T, F: FnOnce(&CriticalSection, &mut T) -> R>(
    m: &Mutex<RefCell<Option<T>>>,
    f: F,
) -> Option<R> {
    free(|cs| m.borrow(cs).borrow_mut().as_mut().map(|x| f(cs, x)))
}

/// Example usage for ISR:

#[interrupt]
fn USB_OTHER() {
    poll_usb();
}

#[interrupt]
fn USB_TRCPT0() {
    poll_usb();
}

#[interrupt]
fn USB_TRCPT1() {
    poll_usb();
}

fn poll_usb() {
    free(|cs| {
        if let Some(inf) = USB.borrow(cs).borrow_mut().as_mut() {
            if inf.dev.poll(&mut [&mut inf.can_usb]) {
                inf.class.poll(cs);
            }
        }
    });
}

@kyp44 kyp44 force-pushed the tier1-bsp-usb-examples branch 2 times, most recently from e37b925 to 98d8a06 Compare October 15, 2025 02:47
kyp44 and others added 10 commits October 29, 2025 12:58
…HAL to support refactoring the `feather_m0/adalogger` example.
* For the `adalogger` example, fixes a compiler error by upgrading the `embedded-sdmmc` dependency and migrating to the new API.
* Fixes a minor compiler error in the `adc` example when the `use_semihosting` feature is enabled.
* Fixes a minor compiler warning in the `async_adc` example.
* Fixes a minor compiler warning in the `adc` example.
* Fixes a minor compiler warning in the `async_adc` example.
* Renames `usb_echo` to `usb_echo_basic` and suppresses the `static mut` warnings.
* Adds the `usb_echo_rtic` example showing how using USB is easier with RTIC.
…atics to use `OnceCell` and suppressing the `static mut` warnings:

* `nvm_dsu`
* `pukcc_test`
* `smart_eeprom`
* `usb_echo`
…mut` warnings:

* `adalogger`
* `clock`
* `usb_echo`
@kyp44 kyp44 force-pushed the tier1-bsp-usb-examples branch from 98d8a06 to 4201e2b Compare October 29, 2025 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants